package arithm

import (
	"testing"
)

func TestChooseNumberType(t *testing.T) {
	tests := []struct {
		input    string
		expected NumberType
		hasError bool
	}{
		{"123", INTEGER_TYPE, false},
		{"-456", INTEGER_TYPE, false},
		{"+789", INTEGER_TYPE, false},
		{"123456789012345678901234567890", BIGINTEGER_TYPE, false},
		{"-123456789012345678901234567890", BIGINTEGER_TYPE, false},
		{"1/2", RATIONAL_TYPE, false},
		{"-3/4", RATIONAL_TYPE, false},
		{"+5/6", RATIONAL_TYPE, false},
		{"12.34", REAL_TYPE, false},
		{"-56.78", REAL_TYPE, false},
		{"+90.12", REAL_TYPE, false},
		{"1e10", REAL_TYPE, false},
		{"2E-5", REAL_TYPE, false},
		{"-3.14e+2", REAL_TYPE, false},
		{"1+2i", COMPLEX_TYPE, false},
		{"-3+4i", COMPLEX_TYPE, false},
		{"5-6i", COMPLEX_TYPE, false},
		{"+7+8i", COMPLEX_TYPE, false},
		{"i", COMPLEX_TYPE, false},
		{"+i", COMPLEX_TYPE, false},
		{"-i", COMPLEX_TYPE, false},
		{"123i", COMPLEX_TYPE, false},
		{"4.5i", COMPLEX_TYPE, false},
		{"1/2i", COMPLEX_TYPE, false},
		{"1+2e+1i", COMPLEX_TYPE, false},
		{"invalid", 0, true},
		{"", 0, true},
	}

	for _, test := range tests {
		result, err := getNumberType(test.input)
		if test.hasError {
			if err == nil {
				t.Errorf("chooseNumberType(%s) expected error but got none", test.input)
			}
		} else {
			if err != nil {
				t.Errorf("chooseNumberType(%s) returned unexpected error: %v", test.input, err)
			} else if result != test.expected {
				t.Errorf("chooseNumberType(%s) = %d, want %d", test.input, result, test.expected)
			}
		}
	}
}

func TestGetComplexParts(t *testing.T) {
	tests := []struct {
		input        string
		expectedReal string
		expectedImag string
	}{
		{"1+2i", "1", "2"},
		{"1-2i", "1", "-2"},
		{"-1+2i", "-1", "2"},
		{"-1-2i", "-1", "-2"},
		{"3i", "", "3"},
		{"-4i", "", "-4"},
		{"+5i", "", "5"},
		{"i", "", "1"},
		{"+i", "", "1"},
		{"-i", "", "-1"},
		{"1/2+3/4i", "1/2", "3/4"},
		{"1.5-2.7i", "1.5", "-2.7"},
		{"1+2e+1i", "1", "2e+1"},
		{"2e-3+4e+5i", "2e-3", "4e+5"},
	}

	for _, test := range tests {
		realPart, imagPart := getComplexParts(test.input)
		if realPart != test.expectedReal {
			t.Errorf("getComplexParts(%s) realPart = %s, want %s", test.input, realPart, test.expectedReal)
		}
		if imagPart != test.expectedImag {
			t.Errorf("getComplexParts(%s) imagPart = %s, want %s", test.input, imagPart, test.expectedImag)
		}
	}
}
